#include "stdafx.h"

#if 0


class BTDevice {

public:
	BTDevice(WSAQUERYSET query) 
	: mName( query.lpszServiceInstanceName)
	, mMacAddress(((SOCKADDR_BTH*)query.lpcsaBuffer->RemoteAddr.lpSockaddr)->btAddr)
	, mbthaddr(*(SOCKADDR_BTH*)query.lpcsaBuffer->RemoteAddr.lpSockaddr)
	{}



	// throws SocketException
	static std::vector<BTDevice> queryDevices() {

		std::vector<BTDevice> result;

		WSAQUERYSET querySet = {0};
		querySet.dwSize = sizeof(WSAQUERYSET);
		querySet.dwNameSpace = NS_BTH;
		querySet.lpcsaBuffer = NULL;

		// initiate discovery
		HANDLE hLookup;
		if (::WSALookupServiceBegin( &querySet, LUP_CONTAINERS, &hLookup) 
			== SOCKET_ERROR) throw SocketException(_T("WSALookupServiceBegin: "),  WSAGetLastError());

		CHAR buf[4096];
		LPWSAQUERYSET pwsaResults = (LPWSAQUERYSET) buf;
		ZeroMemory(pwsaResults, sizeof(WSAQUERYSET));
		pwsaResults->dwSize = sizeof(WSAQUERYSET);
		pwsaResults->dwNameSpace = NS_BTH;
		pwsaResults->lpBlob = NULL;
		DWORD dwSize  = sizeof(buf);
		while (::WSALookupServiceNext( hLookup, LUP_RETURN_NAME | LUP_RETURN_ADDR, &dwSize, pwsaResults)
			== ERROR_SUCCESS)
		{
			// extract the MAC Address
			BTDevice device(*pwsaResults);
			result.push_back( device );
		}
		// Check the reason why WSALookupServiceNext stopped
		switch (WSAGetLastError()) {
			// query is done
			case WSA_E_NO_MORE:break;
			case WSAENOMORE:   break;
			// an error occured
			default: throw SocketException(_T("WSALookupServiceNext: "),  WSAGetLastError());
		}

		if (::WSALookupServiceEnd(hLookup)
			== SOCKET_ERROR) throw SocketException(_T("WSALookupServiceEnd: "),  WSAGetLastError());

		return result;
	}

	tstring getName() {
		return mName;
	}

	BTH_ADDR getMacAddress() {
		return mMacAddress;
	}

	SOCKADDR_BTH getbthaddr() {
		return mbthaddr;
	}

private:
	tstring mName;
	BTH_ADDR mMacAddress;
	SOCKADDR_BTH mbthaddr;
};


interface IRunnable  {
public:
	virtual void run() = 0;
};

class Runnable : public IRunnable {
public:
	 virtual void run() override {
		cout << "RUN\n";
	}
};

class Adapter {
public:
	ULONGLONG getMacAddress() {
		return	mMacAddress;
	}

	string getDescription() {
		return mDescription;
	}


	Adapter( IP_ADAPTER_INFO adapterInfo ) 
	: mMacAddress(ntohll( *reinterpret_cast<ULONGLONG*>(adapterInfo.Address)) >>  8 * (sizeof(ULONGLONG) - adapterInfo.AddressLength))
	, mDhcpEnabled( adapterInfo.DhcpEnabled )
	, mName(adapterInfo.AdapterName)
	, mDescription(adapterInfo.Description)
	{}

	// throws SocketException
	static std::vector<Adapter> getAdapters()
	{
		std::vector<Adapter> result;
 
		IP_ADAPTER_INFO AdapterInfo[32];       // Allocate information for up to 32 NICs
		DWORD dwBufLen = sizeof(AdapterInfo);  // Save memory size of buffer
		DWORD dwStatus = GetAdaptersInfo(      // Call GetAdapterInfo
			 AdapterInfo,                 // [out] buffer to receive data
			 &dwBufLen);                  // [in] size of receive data buffer

		//No network card? Other error?
		if (dwStatus != ERROR_SUCCESS) throw SocketException(_T("GetAdaptersInfo: "),  dwStatus);
	
		PIP_ADAPTER_INFO pAdapterInfo = AdapterInfo;
		while(pAdapterInfo)
		{
    		if(pAdapterInfo->Type == MIB_IF_TYPE_ETHERNET)
    		{
    			result.push_back(Adapter(*pAdapterInfo));
    		}
    		pAdapterInfo = pAdapterInfo->Next;
		}
		return result;
	}
private:
	ULONGLONG mMacAddress;
	boolean mDhcpEnabled;
	string mDescription;
	string mName;
};

#endif